home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / MNetsrc.hqx / Mac TCP_IP Source v.33 / fingserv.c < prev    next >
Text File  |  1989-03-01  |  10KB  |  410 lines

  1.  
  2. /*
  3.  *
  4.  *    Finger support...
  5.  *
  6.  *    Finger server routines.  Written by Michael T. Horne - KA7AXD.
  7.  *    Copyright 1988 by Michael T. Horne, All Rights Reserved.
  8.  *    Permission granted for non-commercial use and copying, provided
  9.  *    that this notice is retained.
  10.  *
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include "global.h"
  15. #include "config.h"
  16. #include "mbuf.h"
  17. #include "timer.h"
  18. #include "netuser.h"
  19. #include "tcp.h"
  20. #include "finger.h"
  21.  
  22. struct tcb *fing_tcb = NULLTCB;
  23. int16 finger_notify = 1;
  24.  
  25. finger1(argc, argv)
  26. int    argc;
  27. char    *argv[];
  28. {
  29.     extern int32    ip_addr;
  30.     struct socket    lsocket;
  31.     void        fing_state();
  32.     void        rcv_fing();
  33.  
  34.     if (fing_tcb)
  35.         return;
  36.     /* start finger daemon */
  37.     lsocket.address = ip_addr;
  38.     if(argc < 2)
  39.         lsocket.port = FINGER_PORT;
  40.     else
  41.         lsocket.port = atoi(argv[1]);
  42.     fing_tcb = open_tcp(&lsocket, NULLSOCK, TCP_SERVER, 0, rcv_fing,
  43.         NULLVFP, fing_state, 0, (int *)NULL);
  44.     return;
  45. }
  46. /*
  47.  *    Handle incoming finger connections and closures.
  48.  * 
  49.  */
  50. void
  51. fing_state(tcb,old,new)
  52. struct tcb    *tcb;
  53. char        old,        /* old state */
  54.         new;        /* new state */
  55. {
  56.     struct finger    *fing;
  57.     void        snd_fing();
  58.     char        *a;
  59. #ifdef MAC
  60.     char        *logtime();
  61. #endif
  62.  
  63.     switch(new){
  64.     case ESTABLISHED:
  65.         log(tcb,"open Finger");
  66.         fing = (struct finger *) malloc(sizeof(struct finger));
  67.  
  68.         tcb->user = (char *)fing;    /* Upward pointer */
  69.         fing->tcb = tcb;        /* Downward pointer */
  70.         if (finger_notify)  {
  71. #ifdef MAC
  72.             printf("\007You're being fingered by %s! (%s)\n",
  73.                  psocket(&tcb->conn.remote),logtime());
  74. #else
  75.             printf("\007You're being fingered by %s!\n",
  76.                  psocket(&tcb->conn.remote));
  77. #endif
  78.             fflush(stdout);
  79.         }
  80.         return;
  81.     case CLOSED:
  82.         if (tcb == fing_tcb)
  83.             fing_tcb = NULLTCB;
  84.          if (tcb->user != NULLCHAR)
  85.             free(tcb->user); 
  86.         del_tcp(tcb);
  87.         break;
  88.     }
  89. }
  90.  
  91. /*
  92.  *    Stop the finger server.
  93.  */
  94.  
  95. finger0()
  96. {
  97.     if (fing_tcb != NULLTCB) {
  98.         close_tcp(fing_tcb);
  99.         fing_tcb = NULLTCB;
  100.     }
  101.     return;
  102. }
  103.  
  104. /*
  105.  *    Send a short message on a tcb
  106.  */
  107.  
  108. #ifndef CALLBK
  109. static
  110. #endif
  111. sndmsg(tcb, msg)
  112. struct tcb    *tcb;        /* tcb to send on */
  113. char        *msg;        /* message to send */
  114. {
  115.     struct mbuf *bp;
  116.  
  117.     bp = qdata(msg,(int16)strlen(msg));
  118.     send_tcp(tcb,bp);
  119. }
  120.  
  121. /*
  122.  *    Finger receive upcall.  This is the guts of the finger server.
  123.  *    The user to finger is read from the socket.  If only a newline
  124.  *    is read, then send the remote host a list of all known 'users' on
  125.  *    this system.
  126.  */
  127.  
  128. void
  129. rcv_fing(tcb, ccnt)
  130. register struct tcb    *tcb;
  131. int16            ccnt;
  132. {
  133.     struct finger    *fing;
  134.     FILE        *fuser;
  135.     struct mbuf    *mbuf,
  136.             *bp;
  137.     char        *buf,
  138.             *who,
  139.             *finger_file,
  140. #ifndef MAC
  141.             *path,
  142. #endif
  143.             ch,
  144.             temp[80],
  145.             user[80];
  146.     int        cnt;
  147.     int        size;
  148.  
  149.  
  150.     if ((fing = (struct finger *) tcb->user) == NULLFING)    /* uh oh! */
  151.         return;
  152.     if(recv_tcp(tcb,&bp,FINGNAMELEN) == 0)
  153.         return;
  154.     if ((who = malloc(FINGNAMELEN + 1)) == NULL) {
  155.         free_p(bp);
  156.         return;
  157.     }
  158.  
  159.     cnt = pullup(&bp, who, FINGNAMELEN);    /* get 'user' name */
  160. #ifdef MAC
  161.      free_p(bp);                         /* all done with bp */
  162.  
  163.                                         /* null terminate what we got at */
  164.  
  165.      buf = who;
  166.      while (*buf != '\015' && *buf != '\012'
  167.                       && *buf != '\0' && cnt) {
  168.               buf++;
  169.               cnt--;
  170.      }
  171.      *buf = '\0';
  172.  
  173.      if (*who == '\0') {
  174.  
  175.                                         /* give him a user listing */
  176.  
  177. #else
  178.     who[cnt] = '\0';            /* NULL terminate it */
  179.     free_p(bp);                /* all done with bp */
  180.  
  181.     if (*who == '\015' || *who == '\012') {    /* give him a user listing */
  182. #endif
  183.         int found = 0;
  184. #ifdef MAC
  185.       finger_file = (char *) malloc(strlen(fingerpath) + 1
  186.                        + strlen(fingersuf) + 1);
  187.       if (finger_file ==  NULLCHAR) {     /* uh oh... */
  188.               free(who);                          /* clean up */
  189.               close_tcp(tcb);                   /* close socket */
  190.               return;
  191.       }
  192.   
  193.       /* create wildcard path to finger files */
  194.  
  195.       sprintf(finger_file,"%s*%s", fingerpath, fingersuf);
  196.  
  197.       sndmsg(tcb, "Known users on this system:\015\012");
  198.  
  199.       for (filedir(finger_file, 0, user); user[0] != '\0';
  200.                   filedir(finger_file, 1, user))  {
  201.                   found++;
  202.                   *index(user, '.') = '\0';
  203.                   sprintf(temp, "        %s\015\012", user);
  204.                   sndmsg(tcb, temp);
  205.       }
  206.       if (!found)
  207.               sndmsg(tcb,"None!\015\012");
  208.      }
  209.  else {
  210.  
  211. /* give him a specific user listing */
  212.  
  213. #else
  214.         path = (char *) malloc(strlen(fingerpath) + strlen(fingersuf)
  215.             + 2);
  216.         /* create wildcard path to finger files */
  217.         strcpy(path, fingerpath);
  218.         strcat(path, "*");
  219.         strcat(path, fingersuf);
  220.         sndmsg(tcb, "Known users on this system:\015\012");
  221.         for (filedir(path, 0, user); user[0] != '\0';
  222.             filedir (path, 1, user))  {
  223.             found++;
  224.             *index(user, '.') = '\0';
  225.             sprintf(temp, "        %s\015\012", user);
  226.             sndmsg(tcb, temp);
  227.         }
  228.         if (!found)
  229.             sndmsg(tcb, "None!\015\012");
  230.         free(path);
  231.     }
  232.     else {
  233. #endif
  234. #ifdef CALLBK
  235.         if (*who == '%'){
  236.             mac_callbk(tcb,who);
  237.             free(who);
  238.             close_tcp(tcb);
  239.             return;
  240.         }
  241. #endif
  242.         buf = who;
  243.         while (*buf != '\015' && *buf != '\012' && *buf != '\0')
  244.             buf++;
  245.         *buf = '\0';
  246.         /*
  247.          *    Create path to user's finger file and see if the
  248.          *    the file exists.
  249.          */
  250.         finger_file = malloc(strlen(fingerpath) + strlen(who)
  251.                 + strlen(fingersuf) + 1);
  252.         if (finger_file ==  NULL) {    /* uh oh... */
  253.             free(who);        /* clean up */
  254.             close_tcp(tcb);        /* close socket */
  255.             return;
  256.         }
  257. #ifdef MAC
  258.       sprintf(finger_file, "%s%s%s", fingerpath, who, fingersuf);
  259.  
  260.       if ((fuser = fopen(finger_file, "r")) == (FILE *) NULL) {
  261.                   sprintf(temp, "User %s unknown on this system\015\012", who);
  262.                   sndmsg(tcb, temp);
  263.       }
  264.       else {                   /* valid 'user' */
  265.  
  266.               /*
  267.                * Here's a tricky routine to make sure we get
  268.                * everything in, including "\r\n".  It's needed since
  269.                * UNIX files have only a '\n' for EOL.  What is
  270.                * REALLY NEEDED is a standardized routine for filling
  271.                * mbufs from file input so that each server doesn't
  272.                * have to do it themselves!  Ditto for emptying
  273.                * mbufs!  The problem of "\r\n" doesn't rear its
  274.                * ugly head with MessyDOS, but with UNIX boxes...
  275.                */
  276.  
  277.  
  278.               char        nl = '\0';  /* newline flag */
  279.               char        last = '\0';            /* last character from stream */
  280.  
  281.               ch = fgetc(fuser); /* first get must be outside */
  282.  
  283.               while (!feof(fuser)) {
  284.                size = tcb->window;
  285.                if ((mbuf = alloc_mbuf(size)) == NULLBUF) {
  286.                            fclose(fuser);         /* barf */
  287.                            free(who);                         /* clean up */
  288.                            free(finger_file);
  289.                            close_tcp(tcb);       /* close socket */
  290.                            return;
  291.                }
  292.                buf = mbuf->data; /* pointer to buffer */
  293.  
  294.                while(!feof(fuser) && size--) {       /* loop */
  295.  
  296.      /* if we see an isolated LF or a CR, insert CR followed by LF.
  297.      Ignore a LF that follows a CR in the file input stream. Ignore
  298.      control-Zs all the time. This approach should handle Mac, DOS,
  299.      and UNIX enviroments which may use LF, CR, or CRLF to indicate
  300.      end-of-line. In the packet, we always use CRLF. */
  301.  
  302.                            if (nl) {
  303.                             *buf++ = '\012';   /* LF */
  304.                             mbuf->cnt++;
  305.                             nl--;
  306.                            }
  307.                            else switch(ch) {
  308.                             case '\032':          /* NO ^Z's! */
  309.                              break;
  310.                             case '\012':          /* LF */
  311.                              if (last == '\015')
  312.                                          break;     /* ignore sometimes */
  313.                             case '\015':          /* CR */
  314.                              *buf++ = '\015';
  315.                              mbuf->cnt++;
  316.                              nl++;
  317.                              break;
  318.                             default:
  319.                              *buf++ = ch;
  320.                              mbuf->cnt++;
  321.                              break;
  322.                            }
  323.                            if (!nl) {
  324.                             last = ch;              /* save current character */
  325.                             ch = fgetc(fuser); /* get next character */
  326.                            }
  327.                }
  328.   /* we are at end of window size or at EOF, send what we have */
  329.                send_tcp(tcb, mbuf);          /* send info */
  330.               }
  331.   /* we are at EOF, close file */
  332.               fclose(fuser);
  333.   }
  334.   
  335.  } /* end of all-user or specific-user if-else block */
  336.  
  337.      free(who);                         /* clean up */
  338.      free(finger_file);
  339.      close_tcp(tcb);                  /* close socket */
  340.      return;
  341. #else
  342.         strcpy(finger_file, fingerpath);
  343.         strcat(finger_file, who);
  344.         strcat(finger_file, fingersuf);
  345.  
  346.         if ((fuser = fopen(finger_file, "r")) == (FILE *) NULL) {
  347.             sprintf(temp, "User %s unknown on this system\015\012",
  348.                 who);
  349.             sndmsg(tcb, temp);
  350.         }
  351.         else {                /* valid 'user' */
  352.             char    nl = '\0';    /* newline flag */
  353.  
  354.             /*
  355.              * Here's a tricky routine to make sure we get
  356.              * everything in, including "\r\n".  It's needed since
  357.              * UNIX files have only a '\n' for EOL.  What is
  358.              * REALLY NEEDED is a standardized routine for filling
  359.              * mbufs from file input so that each server doesn't
  360.              * have to do it themselves!  Ditto for emptying
  361.              * mbufs!  The problem of "\r\n" doesn't rear its
  362.              * ugly head with MessyDOS, but with UNIX boxes...
  363.              */
  364.  
  365.             ch = fgetc(fuser);    /* first get must be outside */
  366.             while (!feof(fuser)) {
  367.                 size = tcb->window;
  368.                 if ((mbuf = alloc_mbuf(size)) == NULL) {
  369.                     fclose(fuser);    /* barf */
  370.                     free(who);
  371.                     free(finger_file);
  372.                     return;
  373.                 }
  374.                 buf = mbuf->data;    /* pointer to buffer */
  375.                 while(!feof(fuser) && size--) {    /* loop */
  376.  
  377.                     if (nl) {
  378.                         *buf++ = '\012';/* line feed */
  379.                         mbuf->cnt++;
  380.                         nl--;
  381.                     }
  382.                     else switch(ch) {
  383.                         case '\032':    /* NO ^Z's! */
  384.                             break;
  385.                         case '\012':    /* ignore LF */
  386.                             break;
  387.                         case '\015':    /* EOL */
  388.                             nl++;    /* fall thru */
  389.                         default:
  390.                             *buf++ = ch;
  391.                             mbuf->cnt++;
  392.                             break;
  393.                     }
  394.                     if (!nl)
  395.                         ch = fgetc(fuser);
  396.                 }
  397.                 send_tcp(tcb, mbuf);    /* send info */
  398.             }
  399.             fclose(fuser);
  400.         }
  401.         free(finger_file);
  402.     }
  403.     free(who);
  404.     close_tcp(tcb);            /* close socket */
  405.     return;
  406. #endif
  407. }
  408.  
  409.  
  410.